iT邦幫忙

2023 iThome 鐵人賽

DAY 5
0
自我挑戰組

卡卡嗯的機率實驗筆記系列 第 5

布豐投針問題 Buffon's Needle Problem

  • 分享至 

  • xImage
  •  

法國數學家布豐 (Comte de Buffon, 1707-1788) 在 1733 年提出了著名的投針問題:在一個平面上有距離恰好為 D 的等距直線條紋。現在我們投擲一根長度恰好為 L 的細針,請問有多少機率這根針會與直線條紋相交呢?

這個問題獲得相當大的迴響,一方面或許因為在機率論在賭博界開始默默發展的 18 世紀初,以幾何學結合機率 (Geometric Probability) 在當時是一個很新的研究領域。另一方面,布豐投針問題的答案實在是太漂亮了,而且居然跟 π 有關:當針長 L 不超過條紋間距 D 的時候,針與條紋相交的機率是 2L / (πD),這在計算圓周率的歷史上是會絕對留名的。我們今天就用投針的方法來估計 π 之值吧。

今天除了基本的幾個函式庫以外,還需要 matplotlib 的 collections,這樣可以一口氣繪製很多線段!

from matplotlib import collections as mc

接下來就是主要的模擬丟針部分啦

# 設定間隔與針的長度
D = 1
L = 0.6

xcoords = np.linspace(0, 10 * D, 11)
for x0 in xcoords:
    plt.axvline(x = x0, color = 'k', alpha=0.7, linestyle='-')

# 設定投針的數量
N = 1000

# 模擬在一定範圍內投針
xc = np.random.uniform(0, 10 * D, N)
yc = np.random.uniform(0, 8 * D, N)
tc = np.random.uniform(-np.pi/2, np.pi/2, N)
x1 = xc - np.cos(tc) * L/2
x2 = xc + np.cos(tc) * L/2
y1 = yc - np.sin(tc) * L/2
y2 = yc + np.sin(tc) * L/2

lines = []
for i in range(N):
    lines.append([(x1[i], y1[i]), (x2[i], y2[i])])
    
colors = plt.rcParams['axes.prop_cycle'].by_key()['color']
lc = mc.LineCollection(lines, color=colors)
ax = plt.gca()
ax.add_collection(lc)
ax.autoscale()
plt.title(f"L = {L:.3f}, D = {D:.3f}")

# 計算與條紋相交的針數
count = 0
for i in range(N):
    if np.floor(x1[i]/D) != np.floor(x2[i]/D):
        count += 1

p = count / N
print(f"{N} 針當中有 {count} 根產生交點;估計的 pi 值為 {2*L/D/p:.5f}")

成果如下:

https://ithelp.ithome.com.tw/upload/images/20230920/201123767OH2bIMzGU.png

然後我在找資料的時候發現 Buffon's Needle Problem 居然有個超酷炫延伸版:Buffon's Noodle Problem XD 這個布豐麵條問題是考慮每一次丟的不是直線的針,而是一條彎曲的固定形狀。該問題是直到 19 世紀的 1860 年才被法國數學家 Barbier 提出並解決。詳情可以參考維基百科 https://en.wikipedia.org/wiki/Buffon%27s_noodle


上一篇
伯特蘭悖論 Bertrand's Paradox
下一篇
拒絕抽樣 Rejection Sampling
系列文
卡卡嗯的機率實驗筆記7
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言